package com.share.netdisk.garbage.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.netdisk.garbage.dao.GarbageDao;
import com.share.netdisk.garbage.model.Garbage;
import com.share.netdisk.reclaim.dao.ReclaimDao;
import com.share.netdisk.reclaim.model.Reclaim;
import com.share.netdisk.userhomefile.dao.UserHomeFileDao;
import com.share.netdisk.userhomefile.model.UserHomeFile;
import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@Service
public class GarbageServiceImpl extends ServiceImpl<GarbageDao, Garbage> implements GarbageService {

	private final FileSystem fileSystem;
	private final ReclaimDao reclaimDao;
	private final UserHomeFileDao userHomeFileDao;
	private final GarbageDao garbageDao;

	@Autowired
	public GarbageServiceImpl(FileSystem fileSystem, ReclaimDao reclaimDao, UserHomeFileDao userHomeFileDao, GarbageDao garbageDao) {
		this.fileSystem = fileSystem;
		this.reclaimDao = reclaimDao;
		this.userHomeFileDao = userHomeFileDao;
		this.garbageDao = garbageDao;
	}


	/**
	 * 根据回收站id批量恢复文件
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Map<Integer, String> restoreFilesByReclaimId(List<Integer> reclaimIds) {
		Map<Integer, String> failures = new HashMap<>();

		for (Integer reclaimId : reclaimIds) {
			try {
				// 通过 reclaim_id 获取 home_file_id 和 file_id
				QueryWrapper<Reclaim> queryWrapper = new QueryWrapper<>();
				queryWrapper.eq("reclaim_id", reclaimId);
				Reclaim reclaimRecord = reclaimDao.selectOne(queryWrapper);
				if (reclaimRecord == null || reclaimRecord.getFileId() == null || reclaimRecord.getHomeFileId() == null) {
					log.warn("Reclaim ID {} not found or file ID/home_file_id is invalid.", reclaimId);
					failures.put(reclaimId, "回收站记录未找到或文件ID/用户ID无效");
					continue;
				}
				Integer fileId = reclaimRecord.getFileId(); // 拿到 file_id
				Integer homeFileId = reclaimRecord.getHomeFileId(); // 拿到 home_file_id

				// 使用 file_id 查找 file 表中的记录，以获取 file_url
				Garbage fileInfo = garbageDao.selectById(fileId);
				if (fileInfo == null || fileInfo.getFileUrl() == null) {
					log.warn("File ID {} not found in file table or file URL is missing for reclaim ID {}.", fileId, reclaimId);
					failures.put(reclaimId, "文件路径信息缺失");
					continue;
				}
				String fileUrl = fileInfo.getFileUrl();

				// 使用 home_file_id 查找 user_home_file 表中的记录
				UserHomeFile userHomeFile = userHomeFileDao.selectById(homeFileId);
				if (userHomeFile == null || userHomeFile.getReclaimUrl() == null) {
					log.warn("User home file record not found or reclaim URL is missing for home_file_id {} and reclaim ID {}.", homeFileId, reclaimId);
					failures.put(reclaimId, "缺少必要的路径信息");
					continue;
				}

				// 获取原始路径和回收站路径的 URL
				String originalUrl = userHomeFile.getHomeFileUrl();
				String reclaimUrl = userHomeFile.getReclaimUrl();

				if (originalUrl == null || reclaimUrl == null) {
					log.warn("File ID {} has missing URL information for reclaim ID {}.", fileId, reclaimId);
					failures.put(reclaimId, "缺少必要的路径信息");
					continue;
				}

				// 构建 Path 对象
				Path originalPath = new Path(originalUrl);
				Path trashPath = new Path(reclaimUrl);

				// 检查并恢复 HDFS 中的文件
				if (!fileSystem.exists(trashPath)) {
					log.warn("File ID {} does not exist in HDFS trash path: {} for reclaim ID {}.", fileId, trashPath, reclaimId);
					failures.put(reclaimId, "文件在HDFS回收站中不存在");
					continue;
				}
				if (!fileSystem.rename(trashPath, originalPath)) {
					log.warn("Failed to rename file ID {} from {} to {} for reclaim ID {}.", fileId, trashPath, originalPath, reclaimId);
					failures.put(reclaimId, "文件重命名失败");
					continue;
				}
				log.info("File ID {} has been successfully restored from HDFS for reclaim ID {}.", fileId, reclaimId);


			} catch (IOException e) {
				log.error("Failed to restore file with reclaim ID {} due to HDFS operation error: {}", reclaimId, e.getMessage(), e);
				failures.put(reclaimId, "HDFS操作错误：" + e.getMessage());
			} catch (Exception e) {
				log.error("Unexpected error restoring file with reclaim ID {}: {}", reclaimId, e.getMessage(), e);
				failures.put(reclaimId, "意外错误：" + e.getMessage());
			}
		}

		return failures;
	}

}
